{
  "openapi": "3.1.0",
  "info": {
    "title": "共享资源 API",
    "description": "代理、分组和标签的共享资源管理API。这些资源同时被浏览器环境和云手机使用。基础URL: `http://127.0.0.1:40000`",
    "version": "2026-09-05"
  },
  "tags": [
    {
      "name": "Proxies",
      "description": "Proxies 相关 API。"
    },
    {
      "name": "Groups",
      "description": "Groups 相关 API。"
    },
    {
      "name": "Tags",
      "description": "Tags 相关 API。"
    },
    {
      "name": "Webhooks",
      "description": "团队 Webhook 配置相关 API。"
    }
  ],
  "paths": {
    "/api/proxyInfo/page": {
      "post": {
        "summary": "获取代理列表",
        "deprecated": false,
        "description": "分页列出团队的代理配置。\n\n- **副作用**：无。只读。可带退避安全重试。\n- **说明**：普通成员看不到密码，云代理和动态代理的密码也不会返回。动态代理会出现在这里，但它们由别处管理，无法通过代理接口编辑。",
        "operationId": "queryProxyInfoPageUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^\\d+$",
                    "description": "可选的代理 ID，用于精确匹配。64 位 ID 请以十进制字符串传入，避免精度丢失；不传时不按 ID 筛选。其他筛选条件和分页参数仍然生效。",
                    "example": "1800000000000101"
                  },
                  "pageNo": {
                    "type": "integer",
                    "description": "当前页码（从 1 开始）",
                    "example": 1
                  },
                  "pageSize": {
                    "type": "integer",
                    "description": "每页项目数",
                    "example": 10
                  },
                  "isCloudPhoneProxy": {
                    "type": "boolean",
                    "description": "代理是否用于云手机。\n\n- `true`：排除本地/私有 IP 地址（例如 127.0.0.1、360、pia、私有 IP 地址范围）\n\n- `false`：返回所有代理\n\n",
                    "example": false
                  },
                  "proxyCategoryType": {
                    "type": "integer",
                    "description": "代理类别：\n\n- `1` = 云平台\n\n- `2` = 自有 IP\n\n",
                    "example": 2
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "按代理 IP 地址筛选（部分匹配）",
                    "example": ""
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "按代理名称筛选（部分匹配）",
                    "example": ""
                  },
                  "proxyProviders": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "代理提供商 ID 列表。支持的值：\n\n- `0` = HTTP\n\n- `1` = HTTPS\n\n- `2` = SOCKS5\n\n- `3` = SSH\n\n- `4` = Oxylabs\n\n- `5` = Proxys.io\n\n- `6` = GeoSurf\n\n- `7` = Luminati\n\n- `8` = Lumauto\n\n- `9` = Oxylabsauto\n\n- `10` = Trojan\n\n- `11` = Shadowsocks\n\n- `12` = vmess\n\n- `13` = ABCPROXY\n\n- `14` = LunaProxy\n\n- `15` = IPHTML\n\n- `16` = PiaProxy\n\n- `17` = 922S5\n\n",
                    "example": []
                  },
                  "proxyStatus": {
                    "type": "integer",
                    "description": "代理分配状态：\n\n- `0` = 正常\n\n- `1` = 未分配\n\n- `2` = 正在升级\n\n- `3` = 已过期\n\n- `4` = 即将过期 > 注意：自有代理始终使用状态 `1`。\n\n",
                    "example": 1
                  },
                  "proxyCheckStatus": {
                    "type": "integer",
                    "description": "代理健康检查状态：\n\n- `0` = 待处理\n\n- `1` = 成功\n\n- `2` = 失败\n\n- `3` = 未知错误\n\n",
                    "example": 1
                  },
                  "proxyTypes": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "代理协议类型：\n\n- `0` = HTTP\n\n- `1` = HTTPS\n\n- `2` = SOCKS5\n\n- `3` = SSH\n\n",
                    "example": []
                  }
                },
                "required": []
              },
              "example": {
                "id": "1800000000000101",
                "pageNo": 1,
                "pageSize": 10,
                "isCloudPhoneProxy": false,
                "proxyCategoryType": 2,
                "proxyIp": "",
                "proxyName": "",
                "proxyProviders": [],
                "proxyStatus": 1,
                "proxyCheckStatus": 1,
                "proxyTypes": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data.dataList` 是当前页的记录，无匹配结果时为空数组；`data.total`、`data.current`、`data.pages` 描述分页信息。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "expiryTime": {
                                "description": "过期时间",
                                "type": "string"
                              },
                              "id": {
                                "description": "主键",
                                "type": "string"
                              },
                              "proxyCategoryType": {
                                "description": "代理类型 1：平台代理；2：自有代理",
                                "type": "integer"
                              },
                              "proxyCheckStatus": {
                                "description": "检测状态：0-待检测；1-监控成功；2-检测失败；3-未知错误",
                                "type": "integer"
                              },
                              "state": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "代理所在州或省。优先返回出口 IP 探测地域，缺失时使用配置地域；可能为 null 或空字符串。",
                                "example": "California"
                              },
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "代理所在城市。优先返回出口 IP 探测地域，缺失时使用配置地域；可能为 null 或空字符串。",
                                "example": "Los Angeles"
                              },
                              "proxyPort": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "format": "int32",
                                "description": "代理连接端口，不从代理名称推断；不可用时可能为 null。",
                                "example": 1080
                              },
                              "proxyIp": {
                                "description": "代理IP",
                                "type": "string"
                              },
                              "exportIp": {
                                "description": "出口 IP",
                                "type": "string"
                              },
                              "countryCode": {
                                "description": "国家代码",
                                "type": "string"
                              },
                              "proxyName": {
                                "description": "代理名称",
                                "type": "string"
                              },
                              "proxyProvider": {
                                "description": "代理提供商：默认值 0-HTTP 1-HTTPS 2-SOCKS5 3-SSH 4-Oxylabs 5-Proxys.io 7-Luminati 8-Lumauto 9-Oxylabsauto 10-Trojan 11-Shadowsocks 13-ABCPROXY 14-LunaProxy 15-IPHTML 16-PiaProxy 17-922S5\n\n",
                                "type": "integer"
                              },
                              "proxyType": {
                                "description": "代理类型：0-http 1-https 2-socks5 3-ssh",
                                "type": "integer"
                              },
                              "username": {
                                "description": "代理用户名",
                                "type": "string"
                              },
                              "password": {
                                "description": "代理密码",
                                "type": "string"
                              },
                              "refreshUrl": {
                                "description": "代理刷新 URL",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "current": "1",
                    "dataList": [
                      {
                        "expiryTime": "2026-09-01 12:00:00",
                        "id": "1673823102599682",
                        "proxyCategoryType": 1,
                        "proxyCheckStatus": 1,
                        "state": "California",
                        "city": "Los Angeles",
                        "proxyPort": 1080,
                        "proxyIp": "string",
                        "exportIp": "9222",
                        "countryCode": "string",
                        "proxyName": "example-name",
                        "proxyProvider": 1,
                        "proxyType": 1,
                        "username": "example-name",
                        "password": "string",
                        "refreshUrl": "https://example.com/resource"
                      }
                    ],
                    "pages": "1",
                    "total": "1"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/add": {
      "post": {
        "summary": "添加代理",
        "deprecated": false,
        "description": "在团队中创建一条代理配置。\n\n- **前置条件**：`proxyPort` 必填且必须在 1–65535 之间，`proxyProvider` 必须是已识别的设备服务。\n- **副作用**：写入一条代理记录并返回其 ID，可直接用于绑定浏览器。不会向代理类型发送任何请求。\n- **完成信号**：同步。\n- **重试**：**不做名称或配置的唯一性校验。** 同一个请求体提交两次会产生两条代理、两个 ID。超时后请先在 `/proxyInfo/page` 中检索，再决定是否重发。\n\n已记录的业务错误码：`14023`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "operationId": "addUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "city": {
                    "type": "string",
                    "description": "城市",
                    "example": ""
                  },
                  "country": {
                    "type": "string",
                    "description": "国家代码（ISO 3166-1 alpha-2）。仅当 proxyProvider=17 时才需要。\n\n",
                    "example": "AD"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "加密类型，有效值为 1 到 14 之间的整数。",
                    "example": 14
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "format": "int32",
                    "description": "IP地址变更操作：0 = 阻止，1 = 警告",
                    "example": 1
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "启用 IP 地址变更监控",
                    "example": false
                  },
                  "password": {
                    "type": "string",
                    "description": "代理身份验证密码",
                    "example": ""
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "代理 IP 地址",
                    "example": "8.10.22.46"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "代理名称（支持 {{random}} 等占位符）",
                    "example": "sock5_{{random}}"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "format": "int32",
                    "description": "代理端口号",
                    "example": 65534
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "format": "int32",
                    "description": "代理提供商类型：\n\n0=HTTP，1=HTTPS，2=SOCKS5，3=SSH，4=Oxylabs，5=Proxys.io，6=GeoSurf，7=Luminati，8=Lumauto，9=Oxylabsauto，10=Trojan，11=Shadowsocks，12=vmess，13=ABCPROXY，14=LunaProxy，15=IPHTML，16=PiaProxy，17=922S5。\n\n特殊规则：\n\n- 如果 proxyProvider 为 7 或 8，则 proxyType 为必填项。\n\n- 如果 proxyProvider 为 17，则 country 为必填项；state 和 city 为选填项。\n\n",
                    "example": 2
                  },
                  "proxyType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "代理协议类型：0=HTTP，1=HTTPS，2=SOCKS5，3=SSH。\n\n仅当 proxyProvider 为 7 或 8 时才需要。\n\n",
                    "example": 1
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "用于刷新动态代理 IP 的 URL（如果支持）",
                    "example": ""
                  },
                  "state": {
                    "type": "string",
                    "description": "州/省",
                    "example": ""
                  },
                  "username": {
                    "type": "string",
                    "description": "代理身份验证的用户名",
                    "example": ""
                  }
                },
                "required": [
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ]
              },
              "example": {
                "proxyIp": "8.10.22.46",
                "proxyPort": 65534,
                "proxyProvider": 2,
                "proxyType": 1,
                "country": "AD",
                "state": "",
                "city": "",
                "encryptionType": 14,
                "ipChangeAction": 1,
                "ipMonitor": false,
                "proxyName": "sock5_{{random}}",
                "refreshUrl": "",
                "username": "",
                "password": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个整数值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "代理 ID",
                      "type": "integer"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": 0,
                  "requestId": "abcd1234"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/update": {
      "post": {
        "summary": "修改代理信息",
        "deprecated": false,
        "description": "更新一条代理配置。\n\n- **前置条件**：代理必须存在于团队中。**动态代理不能通过本接口更新。** 设备服务必须是已识别的取值。\n- **副作用**：这是整体覆盖而非局部更新——你省略的字段会回落到默认值，而不是保留当前值。请先读出该代理再完整回传。\n- **生效范围**：浏览器的绑定关系保持不变（因为只有代理记录本身发生变化），但已在运行的浏览器或云手机会继续使用它们启动时的连接信息。请重启它们以采用新配置。\n- **完成信号**：同步。没有乐观锁，并发更新是后写覆盖。\n\n已记录的业务错误码：`14003`, `14023`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "operationId": "updateProxyUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "唯一代理 ID"
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "代理服务器 IP 地址"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "description": "代理服务器端口"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "代理的自定义名称"
                  },
                  "country": {
                    "type": "string",
                    "description": "国家/地区（例如，“US”、“CN”）"
                  },
                  "city": {
                    "type": "string",
                    "description": "城市名称"
                  },
                  "username": {
                    "type": "string",
                    "description": "身份验证用户名（如果需要）"
                  },
                  "password": {
                    "type": "string",
                    "description": "身份验证密码（如果需要）"
                  },
                  "proxyType": {
                    "type": "integer",
                    "description": "代理协议类型：\n\n- `0` = HTTP\n\n- `1` = HTTPS\n\n- `2` = SOCKS5\n\n- `3` = SSH\n\n"
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "description": "代理提供商 ID：\n\n- `0` = HTTP\n\n- `1` = HTTPS\n\n- `2` = SOCKS5\n\n- `3` = SSH\n\n- `4` = Oxylabs\n\n- `5` = Proxys.io\n\n- `6` = GeoSurf\n\n- `7` = Luminati\n\n- `8` = Lumauto\n\n- `9` = Oxylabsauto\n\n- `10` = Trojan\n\n- `11` = Shadowsocks\n\n- `12` = vmess\n\n- `13` = ABCPROXY\n\n- `14` = LunaProxy\n\n- `15` = IPHTML\n\n- `16` = PiaProxy\n\n- `17` = 922S5\n\n"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "description": "加密类型（提供商特定，通常为 0 表示明文）"
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "启用 IP 地址变更监控"
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "description": "IP地址变更时的操作：\n\n- `1` = 通知/刷新（常用值）\n\n> 查看系统文档了解完整选项。\n\n"
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "用于触发 IP 地址刷新的 URL（如果服务提供商支持）"
                  },
                  "state": {
                    "type": "string",
                    "description": "保留字段或自定义状态（可选）"
                  }
                }
              },
              "example": {
                "id": "1566403036579198",
                "proxyIp": "108.11.23.85",
                "proxyPort": 4096,
                "proxyName": "MyProxy",
                "country": "US",
                "city": "New York",
                "username": "",
                "password": "",
                "proxyType": 0,
                "proxyProvider": 0,
                "encryptionType": 0,
                "ipMonitor": true,
                "ipChangeAction": 1,
                "refreshUrl": "",
                "state": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。该接口不返回响应载荷，结果由 `code` 表达。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "efgh5678"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/delete": {
      "post": {
        "summary": "删除代理",
        "deprecated": false,
        "description": "删除一条或多条代理配置。\n\n- **前置条件**：至少有一个 ID 能在团队中解析；解析不到的会被静默忽略。**未过期的云平台代理不可删除**，会返回专门的错误码。\n- **副作用**：自有代理会被移除并解除跳板机绑定。已过期的云平台代理改为标记待释放、取消其订阅，并**异步**释放 IP——响应返回时释放可能仍在进行中。\n- **级联影响**：绑定了该代理的浏览器与云手机**既不会被阻止删除，也不会被解绑**。它们仍指向已删除的代理，运行中的会话不会被中断。删除前请先用 `/env/setProxy/batch` 改绑。\n- **重试**：ID 逐个处理，遇到第一个被拒即中止，因此批量可能部分生效。重试前请重新读取 `/proxyInfo/page`。\n\n已记录的业务错误码：`14017`, `14024`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "operationId": "deleteProxyUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              },
              "example": [
                1054661322597744600,
                1054661322597744600
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。该接口不返回响应载荷，结果由 `code` 表达。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "ijkl9012"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/page": {
      "post": {
        "operationId": "apiEnvgroupPagePost",
        "summary": "获取分组列表",
        "deprecated": false,
        "description": "分页列出浏览器分组。\n\n- **副作用**：无。只读。可带退避安全重试。\n- **说明**：当团队按分组授权时，没有任何分组授权的成员会收到空页而不是报错。",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "groupName": {
                    "type": "string",
                    "title": "分组名称（模糊匹配）"
                  },
                  "pageNo": {
                    "type": "integer",
                    "title": "当前页"
                  },
                  "pageSize": {
                    "type": "integer",
                    "title": "每页条数"
                  }
                },
                "required": [
                  "groupName",
                  "pageNo",
                  "pageSize"
                ]
              },
              "example": {
                "groupName": "132-kernel",
                "pageNo": 1,
                "pageSize": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data.dataList` 是当前页的记录，无匹配结果时为空数组；`data.total`、`data.current`、`data.pages` 描述分页信息。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "分组 ID",
                                "type": "string"
                              },
                              "groupName": {
                                "description": "分组名称",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "current": "0",
                    "dataList": [
                      {
                        "id": "0",
                        "groupName": ""
                      }
                    ],
                    "pages": "0",
                    "total": "0"
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/edit": {
      "post": {
        "operationId": "apiEnvgroupEditPost",
        "summary": "修改分组信息",
        "deprecated": false,
        "description": "重命名一个浏览器分组。\n\n- **前置条件**：分组必须存在于团队中，调用者对它有权限，且新名称不能与其他分组冲突。只有名称确实发生变化时才会做唯一性校验。\n- **副作用**：重命名分组。浏览器仍留在其中——它们通过 ID 引用分组，因此不需要更新其他任何东西。\n- **完成信号**：同步且幂等。",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName",
                  "id"
                ],
                "properties": {
                  "groupName": {
                    "type": "string",
                    "description": "环境分组的新名称"
                  },
                  "id": {
                    "type": "string",
                    "description": "要更新的分组唯一 ID"
                  }
                }
              },
              "example": {
                "groupName": "Group-1574544945848579",
                "id": "1574525425557584"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean",
                      "description": "结果"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": true,
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/create": {
      "post": {
        "operationId": "apiEnvgroupCreatePost",
        "summary": "添加分组",
        "deprecated": false,
        "description": "创建一个浏览器分组。\n\n- **前置条件**：名称不能为空、不超过 100 字符，且不能与团队中已有分组重名。**一个团队最多 1000 个分组。**\n- **副作用**：创建分组。当团队按分组授权且调用者不是所有者时，调用者也会被授予该新分组的访问权限。\n- **完成信号**：同步；`data` 携带新分组 ID。\n- **重试**：重名会被拒绝而不是复用已有分组，因此在「实际成功但你没收到响应」之后重试会得到重名错误——这本身就是第一次已成功的信号。请用 `/envgroup/page` 确认。",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName"
                ],
                "properties": {
                  "groupName": {
                    "description": "分组名称",
                    "type": "string"
                  }
                }
              },
              "example": {
                "groupName": "Group-333"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是对象，包含字段 `id`、`groupName`。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "操作返回的数据",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "分组 ID",
                          "type": "string"
                        },
                        "groupName": {
                          "description": "分组名称",
                          "type": "string"
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "id": "1673823102599682",
                    "groupName": "example-name"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/delete": {
      "post": {
        "operationId": "apiEnvgroupDeletePost",
        "summary": "删除分组",
        "deprecated": false,
        "description": "删除一个或多个浏览器分组。\n\n- **前置条件**：至少有一个 ID 能在团队中解析且调用者对它有权限；解析不到的 ID 会被静默忽略。\n- **副作用**：删除分组及其成员授权关系。原本在分组内的浏览器与云手机变为未分组，因此不会留下悬空的分组引用。若打开「同时删除环境」开关，还会把你有权限的浏览器**移入回收站**——它们不会被销毁，且该开关对云手机始终无效。\n- **完成信号**：同步但**非原子**。分组先被删除，后续步骤仍可能失败（例如浏览器正在运行或处于转移中），结果是分组已消失而浏览器未被移动。\n- **重试**：重试前请用 `/envgroup/page` 和浏览器列表核实。\n\n已记录的业务错误码：`19064`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "待更新分组的唯一 ID"
                  },
                  "isDeleteAllEnv": {
                    "type": "boolean",
                    "description": "是否同时删除分组内的环境？false：不删除　true：删除"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/all": {
      "get": {
        "operationId": "apiEnvtagAllGet",
        "summary": "获取标签列表",
        "deprecated": false,
        "description": "返回团队内所有浏览器标签。\n\n- **副作用**：无。只读。可带退避安全重试。\n- **说明**：本接口**不分页，且标签没有服务端数量上限**，因此响应体会随团队创建的标签数增长。请相应地设计客户端。",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "成功。`data` 是对象数组，元素包含字段 `id`、`tagName`；无数据时返回空数组。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "标签 ID",
                            "type": "string"
                          },
                          "tagName": {
                            "description": "标签名称",
                            "type": "string"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": [
                    {
                      "id": "0",
                      "tagName": ""
                    }
                  ],
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/create": {
      "post": {
        "operationId": "apiEnvtagCreatePost",
        "summary": "创建标签",
        "deprecated": false,
        "description": "创建一个浏览器标签。\n\n- **前置条件**：名称不能为空、不超过 100 字符，且不能与团队中已有标签重名。\n- **副作用**：创建标签并返回其 ID。与分组不同，标签没有数量上限。\n- **重试**：重名会被拒绝而不是复用已有标签。请用 `/envtag/all` 确认。",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tagName"
                ],
                "properties": {
                  "tagName": {
                    "type": "string",
                    "description": "标签名称"
                  }
                }
              },
              "example": {
                "tagName": "Tag-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是对象，包含字段 `id`、`tagName`。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "标签 ID",
                          "type": "string"
                        },
                        "tagName": {
                          "description": "标签名称",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "tagName"
                      ]
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "id": "0",
                    "tagName": ""
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/edit": {
      "post": {
        "operationId": "apiEnvtagEditPost",
        "summary": "修改标签信息",
        "deprecated": false,
        "description": "重命名一个浏览器标签。\n\n- **前置条件**：标签必须存在于团队中，且新名称不能与其他标签冲突。\n- **副作用**：重命名标签。已有的标签挂载关系不受影响，浏览器会立即显示新名称。\n- **完成信号**：同步且幂等。",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "tagName"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "标签 id"
                  },
                  "tagName": {
                    "type": "string",
                    "description": "标签名称"
                  }
                }
              },
              "example": {
                "id": "1564715845550177",
                "tagName": "Updated-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/delete": {
      "post": {
        "operationId": "apiEnvtagDeletePost",
        "summary": "删除标签",
        "deprecated": false,
        "description": "删除一个或多个浏览器标签。\n\n- **前置条件**：至少有一个 ID 能在团队中解析；解析不到的会被静默忽略。\n- **副作用**：删除标签。该标签会从所有携带它的浏览器上消失，且不会删除任何浏览器。本接口只管理浏览器标签——云存储文件标签另有接口。\n- **完成信号**：同步。重复调用会报标签无效，这说明第一次已成功。\n\n已记录的业务错误码：`19105`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "待更新标签的唯一 ID"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是单个布尔值。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果代码 0：正常；其他代码均为例外情况。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/webhook/config": {
      "post": {
        "operationId": "apiWebhookConfigPost",
        "summary": "配置团队 Webhook",
        "deprecated": false,
        "description": "新增或替换团队的 Webhook 配置。\n\n- **前置条件**：`callbackUrl` 必须是 1 到 1024 个字符的 HTTPS 地址，带主机名，不含用户信息与片段，端口合法。它解析到的每个地址都必须是公网可路由的；localhost、内网、链路本地、CGNAT、云元数据、协议保留、文档示例与 6to4 等范围会被拒绝。实际建连时会再校验一次，因此某个域名若之后解析到内网范围，只会导致该次投递失败，不会打到你的内网。\n- **副作用**：按服务端上下文所属团队做唯一配置的 upsert。`teamId` 不从请求读取，因此调用方无法配置其他团队。Local API 与 Open API 两个入口读写同一份记录，响应会回显已保存的内容。\n- **停用**：`enabled: false` 会保留地址并停止创建新事件。已排队的事件在下次被授权时若配置仍处于停用状态，会被逐条取消；因此快速重新启用可以让它们继续投递。\n- **重试**：安全。保存是按团队的 upsert，重复发送同一请求会收敛到同一状态。\n- **客户端版本**：需要 MoreLogin 客户端 v2.66.0 或更高版本，因为本地这条路由是由桌面客户端暴露的。Open API 入口不依赖客户端。\n\n回调契约、事件名称与重试节奏见 [Webhooks](../Getting%20Started/webhooks.md)。\n\n已记录的业务错误码：`41001`。 各错误码的含义见 [Error Codes](../Getting%20Started/error-codes.md)。任何接口还可能返回通用错误码。",
        "tags": [
          "Webhooks"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "description": "接收事件的 HTTPS 地址。1 到 1024 个字符。",
                    "type": "string",
                    "maxLength": 1024
                  },
                  "enabled": {
                    "description": "该团队是否启用投递。",
                    "type": "boolean"
                  }
                },
                "required": [
                  "callbackUrl",
                  "enabled"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/morelogin/webhook",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "成功。`data` 是包含 `callbackUrl` 与 `enabled` 字段的对象，回显已保存的配置。",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "返回结果码，0 表示正常，其他码为异常。",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "错误信息",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "callbackUrl": {
                          "description": "已保存的 HTTPS 回调地址。",
                          "type": "string"
                        },
                        "enabled": {
                          "description": "该团队是否启用投递。",
                          "type": "boolean"
                        }
                      }
                    },
                    "requestId": {
                      "description": "操作请求 ID",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "callbackUrl": "https://example.com/morelogin/webhook",
                    "enabled": true
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    }
  },
  "webhooks": {},
  "components": {
    "securitySchemes": {}
  },
  "servers": [
    {
      "url": "http://127.0.0.1:40000",
      "description": "MoreLogin Local 端点"
    }
  ],
  "security": []
}